package com.yzy.baselibrary.http.response

import com.yzy.baselibrary.base.BaseApplication
import com.yzy.baselibrary.extention.isNetworkAvailable
import com.yzy.baselibrary.extention.toast
import com.blankj.utilcode.util.LogUtils
import io.reactivex.observers.ResourceObserver
import retrofit2.HttpException
import java.net.SocketTimeoutException

/**
 *description: 关心各种状态的请求观察者.
 *@date 2018/10/17 15:47.
 *@author: YinZeYu.
 */
class StatusResourceObserver<T>(private val liveData: StatusDataLiveData<T>) :
    ResourceObserver<T>() {

  companion object {
    var exceptionPretreatment: ((e: Throwable) -> Throwable)? = null
  }

  override fun onStart() {
    super.onStart()
    liveData.value = StatusData.Start()
  }

  override fun onComplete() {
    liveData.value = StatusData.Complete()
  }

  override fun onNext(t: T) {
    when (t) {
      is EmptyData -> {
        //空类型
        liveData.value = StatusData.Empty()
      }
      is List<*> -> {
        //列表
        if (t.isEmpty()) {
          //列表为空
          liveData.value = StatusData.Empty()
        } else {
          liveData.value = StatusData.Success(t)
        }
      }
      else -> {
        liveData.value = StatusData.Success(t)
      }
    }
  }

  override fun onError(e: Throwable) {
    var newE = e
    exceptionPretreatment?.let {
      newE = it.invoke(e)
    }
    if (!BaseApplication.INSTANCE.isNetworkAvailable()) {
      //网络连接不可用
      BaseApplication.INSTANCE.toast("似乎与互联网断开连接")
      liveData.value = StatusData.NetWorkException()
    } else {
      when (newE) {
        is HttpException -> {
          LogUtils.e("请求异常", newE)
          BaseApplication.INSTANCE.toast("啊哦，服务器抽搐了，请稍后重试~")
          liveData.value = StatusData.NetWorkException()
        }
        is SocketTimeoutException -> {
          LogUtils.e("请求超时", newE)
          BaseApplication.INSTANCE.toast("啊哦，服务器抽搐了，请稍后重试~")
          liveData.value = StatusData.NetWorkException()
        }
        is ApiException -> {
          liveData.value = StatusData.ServeException((newE as ApiException).code, (newE as ApiException).msg, (newE as ApiException).fields)
        }
        else -> {
          LogUtils.e("未知错误", newE)
        }
      }
    }
    liveData.value = StatusData.Failure(newE)
    liveData.value = StatusData.Complete()
  }
}